﻿using System.Windows;
using Microsoft.Phone.Scheduler;
using System;
using System.Xml.Serialization;
using System.IO;
using Microsoft.Phone.Shell;
using System.Collections.Generic;
using System.Linq;

namespace NotesAgent
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        private static volatile bool _classInitialized;

        /// <remarks>
        /// ScheduledAgent constructor, initializes the UnhandledException handler
        /// </remarks>
        public ScheduledAgent()
        {
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                });
            }
        }

        /// Code to execute on Unhandled Exceptions
        private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

        /// <summary>
        /// Agent that runs a scheduled task
        /// </summary>
        /// <param name="task">
        /// The invoked task
        /// </param>
        /// <remarks>
        /// This method is called when a periodic or resource intensive task is invoked
        /// </remarks>
        protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background

            Account acc = Storage.LoadAccount();
            if (!acc.IsActive())
                return;

            GetResult(acc, UpdateTiles, () => { });
        }

        public void UpdateTiles(Result result)
        {
            if (result == null) return;
            ShellTile appTile = ShellTile.ActiveTiles.FirstOrDefault();

            try
            {

                if (appTile != null)
                {
                    int val = 0;

                    Result old = Storage.LoadResult();

                    for(int i=0;i<result.notes.Count;i++)
                    {
                        var n = result.notes[i];
                        var o_n = old.notes.First(o => o.Id == n.Id);
                        if (o_n == null)
                        {
                            val++;
                        }
                        else
                        {
                            if (!n.Equals(o_n))
                                val++;
                            result.notes.RemoveAt(i);
                            i--;
                        }
                    }
                    val += result.notes.Count;

                    StandardTileData tileData = new StandardTileData
                    {
                        Count = val
                    };

                    appTile.Update(tileData);


                }
            }
            catch (InvalidOperationException ex)
            {
                ex.ToString();
            }
            catch (Exception ex)
            {
                ex.ToString();
            }

        }

        public static void GetResult(Account currentAccount, Action<Result> callback, Action error)
        {
            string url = "http://fboscari.altervista.org/Notes/get_notes_phone.php?";
            //url += Utils.GetUpdateLiveTileArgs(result, currentAccount.contract, currentAccount.username, currentAccount.password, currentAccount.number, currentAccount.showDate);
            url += "username=" + currentAccount.username + "&pwd=" + currentAccount.password + "&salt=" + DateTime.Now.Millisecond;
            Storage.getHTML(url, s =>
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Result));
                var reader = new StringReader(s);
                Result result = serializer.Deserialize(reader) as Result;

                if (result == null)
                {
                    error();
                }
                result.UpdateChars();
                if (result.err == "0")
                    callback(result);
                else
                    error();

            },
            (e) =>
            {
                error();
            });
        }
    }
}